package com.google.jessewilson.codesearch.ui;

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FunctionList;
import ca.odell.glazedlists.swing.AutoCompleteSupport;
import ca.odell.glazedlists.swing.EventComboBoxModel;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;

/**
 * @author jessewilson
 */
public class HistoryField<T> implements EditorComponent<String> {

  private final EventList<String> choices;
  private final JComboBox field;
  private final FunctionList.Function<T, String> function;

  public HistoryField(FunctionList.Function<T, String> function) {
    this.choices = new BasicEventList<String>();
    this.function = function;

    this.field = new JComboBox(new EventComboBoxModel<String>(choices));
    this.field.setEditable(true);
    AutoCompleteSupport<String> autoCompleteSupport = AutoCompleteSupport.install(field, choices);
    autoCompleteSupport.setStrict(false);
    autoCompleteSupport.setCorrectsCase(false);
    autoCompleteSupport.setSelectsTextOnFocusGain(true);
  }

  public String getValue() {
    if(field.getSelectedItem() == null) {
      return "";
    } else {
      return "" + field.getSelectedItem();
    }
  }

  public void setValue(String value) {
    choices.remove(value);
    choices.remove("");
    choices.add(0, value);
    field.setSelectedIndex(0);
    if(value.length() > 0) {
      choices.add(0, "");
    }
  }

  public JComboBox getComponent() {
    return field;
  }

  public void setHistory(List<T> queryHistory) {
    String previousValue = getValue();

    choices.clear();
    choices.addAll(historyToStrings(queryHistory));

    setValue(previousValue);
  }

  List<String> historyToStrings(List<T> history) {
    List<String> result = new ArrayList<String>();
    for(T historyElement : history) {
      String historyElementAsString = function.evaluate(historyElement);
      if(historyElementAsString == null) {
        continue;
      }
      historyElementAsString = historyElementAsString.trim();
      if(historyElementAsString.length() == 0) {
        continue;
      }
      if(!result.contains(historyElementAsString)) {
        result.add(historyElementAsString);
      }
    }
    return result;
  }

  public void setAction(final Action action) {
    final JTextField editor = (JTextField) field.getEditor().getEditorComponent();
    editor.addKeyListener(new KeyListener() {
      public void keyTyped(KeyEvent e) {
        if(e.getKeyChar() == KeyEvent.VK_ENTER) {
          action.actionPerformed(new ActionEvent(editor, 0, "edited"));
        }
      }
      public void keyPressed(KeyEvent e) {
      }
      public void keyReleased(KeyEvent e) {
      }
    });
  }
}
